# utils.rb : Some utilities to have Qt4 work great with ruby
# Copyright (C) 2006 Vincent Fourmond
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA

require 'Qt4'

class Qt::DateTime

  # Transforms into a ruby Time object
  def to_time
    epoch = Qt::DateTime.new(Qt::Date.new(1970, 1, 1))
    nb = epoch.secs_to(self)
    return Time.at(nb)
  end
end

# A utility module to save/restore objects properties using settings.
module SettingsStorage

  # Helper function to get the object referred to by the first element
  # If the symbol starts with @, we treat it as an instance variable.
  def get_obj(sym)
    return self unless sym      # nil is self
    if sym.to_s =~ /^@/
      return instance_variable_get(sym)
    else
      return self.send(sym)
    end
  end

  # The given function saves settings to the Qt::Settings _settings_
  # object according to the given _specs_. The latter should be in the
  # following format:
  # 
  #  {
  #  "key" => [ :object (or nil for self), :reader,
  #             :writer = :reader= , default_value (or nil for no default)
  #           ]
  #  }
  def save_properties(specs, settings)
    for key, (obj_name, reader, writer, cls) in specs
      obj = get_obj(obj_name)
      value = obj.send(reader)
      settings.set_value(key, qVariantFromValue(value))
    end
  end

  # Restores attributes previously saved with #save_properties
  # If the key is absent in the configuration file, no action is undertaken
  def restore_properties(specs, settings)
    for key, (obj_name, reader, writer, default) in specs
      if settings.contains(key)
        obj = get_obj(obj_name)
        value = settings.value(key)
        # Use an explicit converter in case it is needed.
        writer ||= (reader.to_s + '=').to_sym
        obj.send(writer, value.to_ruby) # to_ruby is perfectly
        # safe in most cases.
      end
    end
  end

end


class Qt::Menu
  
  def add_action(*args, &blk)
    if block_given?
      name, key, target = *args
      target ||= self
      action = Qt::Action.new(name, target)
      add_action(action)
      action.short_cut = key if key
      target.connect(action, SIGNAL('triggered()'), &blk)
      return action
    else
      super
    end
  end

end

  
class Object
  # Easy conversion from any value to Qt::Variant
#   def to_variant
#     return Qt::qVariantFromValue(self)
#   end
end

# A very small calendar editing mode

class DateDialog < Qt::Dialog
  def initialize(date, text, parent)
    super(parent)
    vbox = Qt::VBoxLayout.new(self)
    set_layout(vbox)
    label = Qt::Label.new(text, self)
    vbox.add_widget(label)
    @date_edit = Qt::DateTimeEdit.new(self)
    @date_edit.calendar_popup = true
    @date_edit.date_time = date.to_date_time
    vbox.add_widget(@date_edit)
    
    hbox = Qt::HBoxLayout.new
    vbox.add_item(hbox)

    button = Qt::PushButton.new("OK", self)
    connect(button, SIGNAL("clicked()"), SLOT("accept()"))
    hbox.add_widget(button)

    button = Qt::PushButton.new("Cancel", self)
    connect(button, SIGNAL("clicked()"), SLOT("reject()"))
    hbox.add_widget(button)
  end

  def exec
    val = super
    if val == Qt::Dialog::Accepted
      return @date_edit.date_time.to_time
    else
      return false
    end
  end
end
